home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
embedded
/
68hc11
/
smallc11.arc
/
CC13.C
< prev
next >
Wrap
Text File
|
1988-05-27
|
8KB
|
351 lines
/*
** statement parser
**
** called whenever syntax requires a statement
** this routine performs that statement
** and returns a number telling which one
*/
statement() {
if ((ch==0) & (eof)) return;
else if(amatch("char",4)) {
declloc(CCHAR);
ns();
}
else if(amatch("int",3)) {
declloc(CINT);
ns();
}
else {
if(declared >= 0) {
if(ncmp > 1) nogo=declared; /* disable goto if any */
csp=modstk(csp - declared, NO);
declared = -1;
}
if(match("{")) compound();
else if(amatch("if",2)) {
doif();
lastst=STIF;
}
else if(amatch("while",5)) {
dowhile();
lastst=STWHILE;
}
#ifdef STDO
else if(amatch("do",2)) {
dodo();
lastst=STDO;
}
#endif
#ifdef STFOR
else if(amatch("for",3)) {
dofor();
lastst=STFOR;
}
#endif
#ifdef STSWITCH
else if(amatch("switch",6)) {
doswitch();
lastst=STSWITCH;
}
else if(amatch("case",4)) {
docase();
lastst=STCASE;
}
else if(amatch("default",7)) {
dodefault();
lastst=STDEF;
}
#endif
#ifdef STGOTO
else if(amatch("goto",4)) {
dogoto();
lastst=STGOTO;
}
else if(dolabel()) ;
#endif
else if(amatch("return",6)) {
doreturn();
ns();
lastst=STRETURN;
}
else if(amatch("break",5)) {
dobreak();
ns();
lastst=STBREAK;
}
else if(amatch("continue",8)) {
docont();
ns();
lastst=STCONT;
}
else if(match(";")) errflag=0;
else if(match("#asm")) {
doasm();
lastst=STASM;
}
else {
doexpr();
ns();
lastst=STEXPR;
}
}
return lastst;
}
compound() {
int savcsp;
char *savloc;
savcsp = csp;
savloc = locptr;
declared = 0; /* may now declare local variables */
++ncmp; /* new level open */
while(match("}") == 0) {
if(eof) {
error("no final }");
break;
}
else statement(); /* do one */
}
--ncmp; /* close current level */
csp = modstk(savcsp, NO); /* delete local variable space */
#ifdef STGOTO
cptr = savloc; /* retain labels */
while(cptr < locptr) {
cptr2 = nextsym(cptr);
if(cptr[IDENT] == LABEL) {
while(cptr < cptr2)
*savloc++ = *cptr++;
}
else cptr = cptr2;
}
#endif
locptr = savloc; /* delete local symbols */
declared = -1; /* may not declare variables */
}
doif() {
int flab1,flab2;
flab1 = getlabel(); /* get label for false branch */
test(flab1, YES); /* get expression, & branch false */
statement(); /* if true do a statement */
if(amatch("else",4) == 0) { /* if...else ? */
/* simple if ..print false label */
postlabel(flab1);
return; /* and exit */
}
flab2 = getlabel();
#ifdef STGOTO
if ((lastst != STRETURN) & (lastst != STGOTO))
jump(flab2);
#else
if(lastst != STRETURN)
jump(flab2);
#endif
postlabel(flab1); /* print false label */
statement(); /* and do "else" clause */
postlabel(flab2); /* print true label */
}
doexpr() {
int const1,val;
char *before,*start;
while(1) {
setstage(&before, &start);
expression(&const1, &val);
clearstage(before, start);
if(ch != ',') break;
bump(1);
}
}
dowhile() {
int wq[4]; /* allocate local queue */
addwhile(wq); /* add entry to queu for break */
postlabel(wq[WQLOOP]); /* loop label */
test(wq[WQEXIT], YES); /* see if true */
statement(); /* if so, do a statement */
jump(wq[WQLOOP]); /* loop to label */
postlabel(wq[WQEXIT]); /* exit label */
delwhile(); /* delete queue entry */
}
#ifdef STDO
dodo() {
int wq[4],top;
addwhile(wq);
postlabel(top = getlabel());
statement();
needtoken("while");
postlabel(wq[WQLOOP]);
test(wq[WQEXIT], YES);
jump(top);
postlabel(wq[WQEXIT]);
delwhile();
ns();
}
#endif
#ifdef STFOR
dofor() {
int wq[4],lab1,lab2;
addwhile(wq);
lab1 = getlabel();
lab2 = getlabel();
needtoken("(");
if(match(";") == 0) {
doexpr();
ns(); /* expr1 */
}
postlabel(lab1);
if(match(";") == 0) {
test(wq[WQEXIT], NO); /* expr2 */
ns();
}
jump(lab2);
postlabel(wq[WQLOOP]);
if(match(")") == 0) {
doexpr(); /* expr3 */
needtoken(")");
}
jump(lab1);
postlabel(lab2);
statement();
jump(wq[WQLOOP]);
postlabel(wq[WQEXIT]);
delwhile();
}
#endif
#ifdef STSWITCH
doswitch() {
int wq[4],endlab,swact,swdef,*swnex,*swptr;
swact = swactive;
swdef = swdefault;
swnex = swptr = swnext;
addwhile(wq);
needtoken("(");
doexpr(); /* evaluate switch expression */
needtoken(")");
swdefault = 0;
swactive = 1;
jump(endlab = getlabel());
statement(); /* cases, etc */
jump(wq[WQEXIT]);
postlabel(endlab);
sw(); /* match cases */
while(swptr < swnext) {
defstorage(CINT>>2);
printlabel(*swptr++); /* case label */
outbyte(',');
outdec(*swptr++); /* case value */
nl();
}
defstorage(CINT>>2);
outdec(0);
nl();
if(swdefault) jump(swdefault);
postlabel(wq[WQEXIT]);
delwhile();
swnext = swnex;
swdefault = swdef;
swactive = swact;
}
docase() {
if(swactive == 0) error("not in switch");
if(swnext > swend) {
error("too many cases");
return;
}
postlabel(*swnext++ = getlabel());
constexpr(swnext++);
needtoken(":");
}
dodefault() {
if(swactive) {
if(swdefault) error("multiple defaults");
}
else error("not in switch");
needtoken(":");
postlabel(swdefault = getlabel());
}
#endif
#ifdef STGOTO
dogoto() {
if(nogo > 0) error("not allowed with block-locals");
else noloc = 1;
if(symname(ssname, YES)) jump(addlabel());
else error("bad label");
ns();
}
dolabel() {
char *savelptr;
blanks();
savelptr = lptr;
if(symname(ssname, YES)) {
if(gch() == ':') {
postlabel(addlabel());
return 1;
}
else bump(savelptr-lptr);
}
return 0;
}
addlabel() {
if(cptr = findloc(ssname)) {
if(cptr[IDENT] != LABEL) error("not a label");
}
else cptr = addsym(ssname,LABEL,LABEL,getlabel(),&locptr,LABEL);
return (getint(cptr+OFFSET, OFFSIZE));
}
#endif
doreturn() {
if(endst() == 0) {
doexpr();
modstk(0, YES);
}
else modstk(0, NO);
ret();
}
dobreak() {
int *ptr;
if((ptr = readwhile()) == 0) return; /* no loops open */
modstk((ptr[WQSP]), NO); /* clean up stack ptr */
jump(ptr[WQEXIT]); /* jump to exit label */
}
docont() {
int *ptr;
if((ptr = readwhile()) == 0) return; /* no loops open */
modstk((ptr[WQSP]), NO); /* clean up stack ptr */
jump(wq[WQLOOP]); /* jump to loop label */
}
doasm() {
ccode = 0; /* mark mode as "asm" */
while(1) {
inline();
if(match("#endasm")) break;
if(eof) break;
printf("%s\n",line);
}
kill();
ccode = 1;
}
stowlit(value, size) int value, size; {
if((litptr+size) >= LITMAX) {
printf("**** SMALL-C: literal queue overflow ****\n");
exit(-1);
}
putint(value, litq+litptr, size);
litptr=litptr+size;
}